/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.controller.services;

import com.thienloc.omap.controller.BaseBean;
import com.thienloc.omap.entity.BoSoTrungThuong;
import com.thienloc.omap.entity.TinhCauRs;
import com.thienloc.omap.session.BoSoTrungThuongFacade;
import com.thienloc.omap.session.TinhCauRsFacade;
import com.thienloc.omap.util.JsfUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

/**
 *
 * @author GiangLT
 */
@ManagedBean
@ViewScoped
public class CauCalculatorBean extends BaseBean implements Serializable {

    @EJB
    private TinhCauRsFacade tinhCauRsFacade;
    @EJB
    private BoSoTrungThuongFacade boSoTrungThuongFacade;
    private List<BoSoTrungThuong> list = new ArrayList<BoSoTrungThuong>();
    private TinhCauRs tinhCauRs;
    private Integer number = 0;
    private Boolean calculateSuccessful;
    private Boolean calculateFailed;
    private Boolean calculating;
    private Boolean calculatable;
    private final Logger logger = LoggerFactory.getLogger(CauCalculatorBean.class);

    @PostConstruct
    public void init() {
        try {
            List<TinhCauRs> tinhCauRses = tinhCauRsFacade.findAll();
            if (!tinhCauRses.isEmpty()) {
                tinhCauRs = tinhCauRses.remove(0);
                Calendar lastCalculateTime = Calendar.getInstance();
                lastCalculateTime.setTime(tinhCauRs.getTinhCauRsPK().getTime());

                Calendar now = Calendar.getInstance();

                Calendar time12h = Calendar.getInstance();
                time12h.set(Calendar.HOUR_OF_DAY, 12);
                time12h.set(Calendar.MINUTE, 0);
                time12h.set(Calendar.SECOND, 0);

                Calendar time20h = Calendar.getInstance();
                time20h.set(Calendar.HOUR_OF_DAY, 19);
                time20h.set(Calendar.MINUTE, 45);
                time20h.set(Calendar.SECOND, 0);

                if (now.before(time12h)) { // truoc 12h
                    number = 1;
                    Calendar time20hYesterday = Calendar.getInstance();
                    time20hYesterday.add(Calendar.DATE, -1);
                    time20hYesterday.set(Calendar.HOUR_OF_DAY, 20);
                    time20hYesterday.set(Calendar.MINUTE, 0);
                    time20hYesterday.set(Calendar.SECOND, 0);

                    if (lastCalculateTime.before(time20hYesterday)) { //ket qua ngay hom trc
                        calculateSuccessful = false;
                        calculatable = true;
                        calculateFailed = false;
                        calculating = false;
                    } else {
                        calProcess(tinhCauRs);
                    }
                } else if (now.after(time20h)) { //sau 20h
                    number = 0;
                    Calendar time0h = Calendar.getInstance();
                    time0h.set(Calendar.HOUR_OF_DAY, 0);
                    time0h.set(Calendar.MINUTE, 0);
                    time0h.set(Calendar.SECOND, 0);
                    if (lastCalculateTime.before(time20h)) { //ket qua hom nay
                        calculateSuccessful = false;
                        calculatable = true;
                        calculateFailed = false;
                        calculating = false;
                    } else {
                        calProcess(tinhCauRs);
                    }
                } else { // hien tai giua 12h-20h
                    calculateSuccessful = false;
                    calculatable = false;
                    calculateFailed = false;
                    calculating = false;
                }
            } else {
                calculateSuccessful = false;
                calculatable = true;
                calculateFailed = false;
                calculating = false;
            }

            if (calculateSuccessful) {
                list = boSoTrungThuongFacade.findLatest(number);
            }

        } catch (Exception ex) {
            logger.error("[{}]: ", getUsername(), ex);
            JsfUtil.addErrorMessage("Error", ex.getMessage());
        }
    }

    private void calProcess(TinhCauRs tinhCauRs) {
        switch (tinhCauRs.getTinhCauRsPK().getResult()) {
            case 0:
                calculateSuccessful = true;
                calculatable = false;
                calculateFailed = false;
                calculating = false;
                break;
            case 1:
                calculateSuccessful = false;
                calculatable = false;
                calculateFailed = true;
                calculating = false;
                break;
            case 2:
                calculateSuccessful = false;
                calculatable = false;
                calculateFailed = false;
                calculating = true;
                break;
        }
    }

    public void tinhCau() {
        Runnable tinhCauThread = new Runnable() {

            @Override
            public void run() {
                try {
                    tinhCauRsFacade.tinhCau(number);
                } catch (Exception ex) {
                    logger.error("[{}]: ", getUsername(), ex);
                }
            }
        };
        Executors.newSingleThreadExecutor().execute(tinhCauThread);

    }

    public List<BoSoTrungThuong> getList() {
        return list;
    }

    public void setList(List<BoSoTrungThuong> list) {
        this.list = list;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public TinhCauRs getTinhCauRs() {
        return tinhCauRs;
    }

    public void setTinhCauRs(TinhCauRs tinhCauRs) {
        this.tinhCauRs = tinhCauRs;
    }

    public Boolean getCalculatable() {
        return calculatable;
    }

    public void setCalculatable(Boolean calculatable) {
        this.calculatable = calculatable;
    }

    public Boolean getCalculateFailed() {
        return calculateFailed;
    }

    public void setCalculateFailed(Boolean calculateFailed) {
        this.calculateFailed = calculateFailed;
    }

    public Boolean getCalculateSuccessful() {
        return calculateSuccessful;
    }

    public void setCalculateSuccessful(Boolean calculateSuccessful) {
        this.calculateSuccessful = calculateSuccessful;
    }

    public Boolean getCalculating() {
        return calculating;
    }

    public void setCalculating(Boolean calculating) {
        this.calculating = calculating;
    }
}
